package by.bsu.scs.presentation.action;

import java.io.File;
import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.apache.struts.util.LabelValueBean;

import by.bsu.scs.db.dao.DisciplineTaskHome;
import by.bsu.scs.db.dao.MessageAttachmentHome;
import by.bsu.scs.db.dao.MessageHome;
import by.bsu.scs.model.DisciplineTask;
import by.bsu.scs.model.Message;
import by.bsu.scs.model.MessageAttachment;
import by.bsu.scs.presentation.form.MessageForm;
import by.bsu.scs.util.form.FileManager;
import by.bsu.scs.util.form.MessageFormFiller;
import by.bsu.scs.util.manager.SessionManager;

/**
 * @author Svetlana Voiteh
 * @version 1.0
 * 
 * All actions connected with messages.
 */

public class MessageAction extends DispatchAction {

	private static final String INDEX = "index";
	private static final String STATUS = "status";
	private static final String TASK_ID = "taskId";
	private static final String STUDENT = "student";
	private static final String INSTRUCTOR = "instructor";

	/*
	 * find forward for instructor
	 */
	private static final String LIST_INSTRUCTOR = "listInstructor";
	private static final String SEND_LIST_INSTRUCTOR = "sendListInstructor";
	private static final String CREATE_INSTRUCTOR = "createInstructor";
	private static final String ANSWER_INSTRUCTOR = "answerInstructor";
	private static final String SEND_INSTRUCTOR = "sendInstructor";
	private static final String UPDATE = "update";
	private static final String UPDATE_AJAX = "updateAjax";
	private static final String NOT_READ_AJAX = "notReadAjax";

	/* 
	 * find forward for student
	 */
	private static final String ANSWER_STUDENT = "answerStudent";
	private static final String CREATE_STUDENT = "createStudent";
	private static final String LIST_STUDENT = "listStudent";
	private static final String SEND_LIST_STUDENT = "sendListStudent";
	private static final String SEND_STUDENT = "sendStudent";
	private static final String QUESTION = "question";

	 
	/**
	 * Download file
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward download(ActionMapping mapping, ActionForm form,
	HttpServletRequest request, HttpServletResponse response) {
		
		MessageForm messageForm = (MessageForm) form;
		File file = messageForm.getFile();
		FileManager fileDownload = new FileManager();
		fileDownload.download(file, response);
		
		return null;
	}
	
	/**
	 * Заполняет элементы формы для создания сообщения
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward create(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		MessageForm messageForm = (MessageForm) form;
		MessageFormFiller mesFormFiller = new MessageFormFiller(messageForm,
				SessionManager.getInstance().getUser(request));
		mesFormFiller.clearAll();
		String result = null;
		String userRole = SessionManager.getInstance().getUser(request)
				.getUserRole().getRoleName();
		/*
		 * Если преподаватель создает сообщение
		 */
		if (INSTRUCTOR.equalsIgnoreCase(userRole)) {
			mesFormFiller.fillElementsForInstructor();
			result = CREATE_INSTRUCTOR;
		}
		/*
		 * Если студент создает сообщение
		 */
		if (STUDENT.equalsIgnoreCase(userRole)) {
			mesFormFiller.fillElementsForStudent();
			result = CREATE_STUDENT;
		}
		
		return mapping.findForward(result);
	}

	/**
	 * Отвечает за фильтрацию списка студентов по различным критериям,
	 * когда преподаватель создает письмо студенту.
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward update(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {

		MessageForm messageForm = (MessageForm) form;
		MessageFormFiller mesFormFiller = new MessageFormFiller(messageForm,
				SessionManager.getInstance().getUser(request));
		mesFormFiller.filterStudents();
		return mapping.findForward(UPDATE_AJAX);
	}
	
	/**
	 * Формирует список непрочитанных сообщений.
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward notReadMessages(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		MessageForm messageForm = (MessageForm) form;
		MessageFormFiller mesFormFiller = new MessageFormFiller(messageForm,
				SessionManager.getInstance().getUser(request));
		mesFormFiller.clearAll();
		
		messageForm.setMessageList((ArrayList<Message>) new MessageHome()
		.getNotReadMessagesByIdUserTo(SessionManager.getInstance().getUser(
				request)));
		messageForm.setCountNotReadMessages(messageForm.getMessageList().size());
		
		return mapping.findForward(NOT_READ_AJAX);
	}

	/**
	 * Send message
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward send(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		MessageForm messageForm = (MessageForm) form;
		
		MessageFormFiller mesFormFiller = new MessageFormFiller(messageForm,
				SessionManager.getInstance().getUser(request));
		String result = null;
		String userRole = SessionManager.getInstance().getUser(request)
				.getUserRole().getRoleName();
		Message messageSend = null;

		/*
		 * если преподаватель отправляет собщение
		 */
		if (INSTRUCTOR.equalsIgnoreCase(userRole)) {
			/* 
			 * if send message to one student
			 */
			if (messageForm.getUserToId() != 0) {
				messageSend = mesFormFiller.createMessageSendForInstructor();
				(new MessageHome()).persist(messageSend);
				// if file upload exist
				if (mesFormFiller.isFileUploadExist()) {
					new MessageAttachmentHome().persist(mesFormFiller
							.createMessageAttachement(this, messageSend));
				}

			}
			/*
			 *  if send message to all students
			 */
			else {
				for (LabelValueBean lvb : messageForm.getUserList()) {
					messageForm.setUserToId(Integer.parseInt(lvb.getValue()));
					messageSend = mesFormFiller
							.createMessageSendForInstructor();
					(new MessageHome()).persist(messageSend);
					/*
					 *  if file upload exist
					 */
					if (mesFormFiller.isFileUploadExist()) {
						new MessageAttachmentHome().persist(mesFormFiller
								.createMessageAttachement(this, messageSend));
					}
				}
			}
			result = SEND_INSTRUCTOR;
		}
		/*
		 * если студент отправляет собщение
		 */
		if (STUDENT.equalsIgnoreCase(userRole)) {
			messageSend = mesFormFiller.createMessageSendForStudent();
			(new MessageHome()).persist(messageSend);
			/*
			 *  if file upload exist
			 */
			if (mesFormFiller.isFileUploadExist()) {
				new MessageAttachmentHome().persist(mesFormFiller
						.createMessageAttachement(this, messageSend));
			}
			result = SEND_STUDENT;
		}

		mesFormFiller.clearAll();
		return mapping.findForward(result);
	}

	/**
	 * Create list of messages
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward list(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		MessageForm messageForm = (MessageForm) form;
		MessageFormFiller mesFormFiller = new MessageFormFiller(messageForm,
				SessionManager.getInstance().getUser(request));
		mesFormFiller.clearAll();
		String status = request.getParameter(STATUS);
		/*
		 *  if list of receive messages
		 */
		if (messageForm.RECEIVE_MESSAGES.equalsIgnoreCase(status)) {
			/*
			 *  set new list of receive messages
			 */
			messageForm.setMessageList((ArrayList<Message>) new MessageHome()
					.getMessageByIdUserTo(SessionManager.getInstance().getUser(
							request)));
		}
		/*
		 *  if list of send messages
		 */
		if (messageForm.SEND_MESSAGES.equalsIgnoreCase(status)) {
			/*
			 *  set new list of send messages
			 */
			messageForm.setMessageList((ArrayList<Message>) new MessageHome()
					.getMessageByIdUserFrom(SessionManager.getInstance()
							.getUser(request)));
		}

		String userRole = SessionManager.getInstance().getUser(request)
				.getUserRole().getRoleName();

		return mapping.findForward(getResult(status, messageForm, userRole));
	}

	/**
	 * Delete message from list of messages
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		MessageForm messageForm = (MessageForm) form;
		/*
		 *  Определяет с какого списка (отправленных или принятых)
		 *  сообщений происходит удаление сообщения.
		 */
		String status = request.getParameter(STATUS);

		Message message = new Message();
		/*
		 *  get message that need to delete
		 */
		message = messageForm.getMessageList().get(
				Integer.parseInt(request.getParameter(INDEX)));

		/*
		 *  if list of receive messages
		 */
		if (messageForm.RECEIVE_MESSAGES.equalsIgnoreCase(status)) {
			message.setIsVisibleReceiver(false);
			new MessageHome().merge(message);
			messageForm.setMessageList((ArrayList<Message>) new MessageHome()
					.getMessageByIdUserTo(SessionManager.getInstance().getUser(
							request)));
		}
		/*
		 *  if list of send messages
		 */
		if (messageForm.SEND_MESSAGES.equalsIgnoreCase(status)) {
			message.setIsVisibleSender(false);
			new MessageHome().merge(message);
			messageForm.setMessageList((ArrayList<Message>) new MessageHome()
					.getMessageByIdUserFrom(SessionManager.getInstance()
							.getUser(request)));
		}

		String userRole = SessionManager.getInstance().getUser(request)
				.getUserRole().getRoleName();

		return mapping.findForward(getResult(status, messageForm, userRole));
	}

	/**
	 * Заполняет элементы формы для ответа на принятое сообщение
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward answer(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		MessageForm messageForm = (MessageForm) form;

		Message messageAnswer = new Message();
		messageAnswer = messageForm.getMessageList().get(
				Integer.parseInt(request.getParameter(INDEX)));

		/*
		 *  если сообщение не было прочитано
		 */
		if (!messageAnswer.isIsRead()) {
			/*
			 *  устанавливаем, что оно прочитано
			 */
			messageAnswer.setIsRead(true);
			new MessageHome().merge(messageAnswer);
		}

		/*
		 *  if exist attach file to message
		 */
		ArrayList<MessageAttachment> messageAttachment = new MessageAttachmentHome()
				.getMessageAttachmentByMessage(messageAnswer);
		if (!messageAttachment.isEmpty()) {
				messageForm.setFile(new File(messageAttachment.get(0).getFilePath()));
		}
		else{
			messageForm.setFile(new File(""));
		}
		
		messageForm.setMessageAnswer(messageAnswer);
		messageForm.setUserToId(messageAnswer.getUserFrom().getUserId());

		String result = null;
		String userRole = SessionManager.getInstance().getUser(request)
				.getUserRole().getRoleName();
		/*
		 * если преподаватель отвечает на сообщение
		 */
		if (INSTRUCTOR.equalsIgnoreCase(userRole)) {
			result = ANSWER_INSTRUCTOR;
		}
		/*
		 * если студент отвечает на сообщение
		 */
		if (STUDENT.equalsIgnoreCase(userRole)) {
			result = ANSWER_STUDENT;
		}

		return mapping.findForward(result);
	}

	/**
	 * Заполняет элементы формы для вопроса преподавателю по конкретному заданию
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return mapping forward path
	 */
	public ActionForward question(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		MessageForm messageForm = (MessageForm) form;
		DisciplineTask diTask = new DisciplineTaskHome()
				.getDisciplineTaskByTaskId(Integer.parseInt(request
						.getParameter(TASK_ID)));
		MessageFormFiller mesFormFiller = new MessageFormFiller(messageForm,
				SessionManager.getInstance().getUser(request));
		mesFormFiller.createMessageQuestion(diTask);
		return mapping.findForward(QUESTION);
	}

	/**
	 * Define the mapping forward path
	 * Only for methods list(...) and delete(...)
	 * 
	 * @param String status
	 * @param MessageForm form
	 * @param String userRole
	 * @return String result
	 */
	private String getResult(String status, MessageForm form, String userRole) {
		String result = null;
		/*
		 *  if instructor
		 */
		if (INSTRUCTOR.equalsIgnoreCase(userRole)) {
			if (form.RECEIVE_MESSAGES.equalsIgnoreCase(status)) {
				result = LIST_INSTRUCTOR;
			}
			if (form.SEND_MESSAGES.equalsIgnoreCase(status)) {
				result = SEND_LIST_INSTRUCTOR;
			}
		}
		/*
		 *  if student
		 */
		if (STUDENT.equalsIgnoreCase(userRole)) {
			if (form.RECEIVE_MESSAGES.equalsIgnoreCase(status)) {
				result = LIST_STUDENT;
			}
			if (form.SEND_MESSAGES.equalsIgnoreCase(status)) {
				result = SEND_LIST_STUDENT;
			}
		}
		return result;
	}
}
